home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 …SCII & the Runetime Code / ADC Developer CD (1992-07) (''Butch ASCII And The Runtime Code'')_iso / Dev.CD 199207.iso / Tools & Apps / OS⁄Toolbox / Apple Events / AE Word Services 1.0d6 / Writeswell Jr. Source / ObWind.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-23  |  10.4 KB  |  442 lines  |  [TEXT/KAHL]

  1. /* ObWind.c
  2.  * Routines to handle cWindow objects
  3.  * ©1992 Working Software, Inc.
  4.  * This source code is copyrighted.  Permission is granted to use the Word Services
  5.  * portion of the Writeswell Jr. source code in your own programs, but you 
  6.  * may not distribute the Writeswell Jr. word-processor code as a 
  7.  * commercial product.  If you modify the code, please do not call it 
  8.  * Writeswell Jr. (or Writeswell.)  This will ensure that people understand the 
  9.  * program and don’t have to deal with a number of different versions with 
  10.  * who-knows-what going on in the code.
  11.  * 
  12.  * Writeswell Jr. and Writeswell are trademarks of Working Software, Inc.
  13.  * 24 Dec 91 Mike Crawford
  14.  */
  15. #include <AppleEvents.h>
  16. #include <AEObjects.h>
  17. #include <AEPackObject.h>
  18. #include <AERegistry.h>
  19. #include "AppEvents.h"
  20. #include "ObWind.h"
  21. #include "ObText.h"
  22. #include "Gripe.h"
  23.  
  24. OSErr WindGetDataHandler( AEDesc *tokenPtr,
  25.                         AppleEvent *theAppleEventPtr,
  26.                         AppleEvent *replyEventPtr,
  27.                         long refCon );
  28. OSErr WindSetDataHandler( AEDesc *tokenPtr,
  29.                         AppleEvent *theAppleEventPtr,
  30.                         AppleEvent *replyEventPtr,
  31.                         long refCon );
  32.  
  33. /* Given the the direct object of an event is a window token (or property thereof),
  34.  * do the requested event.
  35.  */
  36. OSErr DispatchWind( AEDesc *tokenPtr,
  37.                         AppleEvent *theAppleEventPtr,
  38.                         AppleEvent *replyEventPtr,
  39.                         long refCon )
  40. {
  41.     OSErr            err;
  42.     AEEventClass    theClass;
  43.     AEEventID        theID;
  44.     
  45.     /* This function is only for the Core suit.  Get the event ID from the appleEvent
  46.      */
  47.     
  48.     err = GetEventID( theAppleEventPtr, &theID );
  49.     
  50.     switch ( theID ){
  51.         case kAEGetData:
  52.             err = WindGetDataHandler( tokenPtr, theAppleEventPtr, replyEventPtr, refCon );
  53.             break;
  54.         case kAESetData:
  55.             err = WindSetDataHandler( tokenPtr, theAppleEventPtr, replyEventPtr, refCon );
  56.             break;
  57.         default:
  58.             err = errAEEventNotHandled;
  59.             break;
  60.     }
  61.     
  62.     return noErr;
  63. }
  64.  
  65. /* The handlers for the various events */
  66.  
  67. /* Get Data */
  68.  
  69. OSErr WindGetDataHandler( AEDesc *tokenPtr,
  70.                         AppleEvent *theAppleEventPtr,
  71.                         AppleEvent *replyEventPtr,
  72.                         long refCon )
  73. {
  74.     WindowPtr        wp;
  75.     DescType        propCode;
  76.     WindTokenBody    **tokHdl;
  77.     AEDesc            replyValue;
  78.     Str255            tmpStr;
  79.     OSErr            err;
  80.  
  81.     /* Sanity check */
  82.     if ( tokenPtr->descriptorType != cWindow ){
  83.         Gripe( "\pGot wrong token type" );
  84.         return errAEEventNotHandled;
  85.     }
  86.  
  87.     tokHdl = (WindTokenBody**)(tokenPtr->dataHandle);
  88.     
  89.     wp = (*tokHdl)->theWindowPtr;
  90.     propCode = (*tokHdl)->propertyCode;
  91.     
  92.     if ( !wp ){
  93.         Gripe( "\pAttempting to get data for non-existent window" );
  94.         return errAENoSuchObject;
  95.     }
  96.  
  97.     switch ( propCode ){
  98.         case typeNull:
  99.             /* This is a magic number for "Not A Property".  I don't know if this
  100.              * is really kosher - gotta ask, but it is a convenience.
  101.              */
  102.             
  103.             /* Should return a string for object browsers */
  104.             Gripe( "\pTrying to GetData on a window object" );
  105.             return errAENoSuchObject;
  106.             break;
  107.         case pName:
  108.             GetWTitle( wp, tmpStr );
  109.                         
  110.             err = AECreateDesc( typeChar,
  111.                                 (Ptr)&(tmpStr[1]),
  112.                                 (Size)tmpStr[0],
  113.                                 &replyValue );
  114.             if ( err ){
  115.                 Gripe( "\pAECreateDesc failed" );
  116.                 return err;
  117.             }
  118.             break;
  119.         case pBounds:
  120.         case pClass:
  121.         case pHasTitleBar:
  122.         case pIndex:
  123.         case pIsModal:
  124.         case pIsResizable:
  125.         case pIsZoomed:
  126.         case pVisible:
  127.             Gripe( "\pGot a property type we do not yet implement" );
  128.             return errAENoSuchObject;
  129.             break;
  130.         default:
  131.             Gripe( "\pUnknown property type" );
  132.             return errAENoSuchObject;
  133.             break;
  134.     }
  135.     
  136.     /* At this point we have some kind of descriptor to stick in the reply */
  137.     
  138.     err = AEPutParamDesc( replyEventPtr,
  139.                             keyDirectObject,
  140.                             &replyValue );
  141.     if ( err ){
  142.         Gripe( "\pAEPutParamDesc failed" );
  143.         return err;
  144.     }
  145.     
  146.     /* It's not clear to me if I should dispose of the reply descriptor here or not */
  147.  
  148.     return noErr;
  149. }/* WindGetDataHandler */
  150.  
  151. /* Set Data */
  152.  
  153. OSErr WindSetDataHandler( AEDesc *tokenPtr,
  154.                         AppleEvent *theAppleEventPtr,
  155.                         AppleEvent *replyEventPtr,
  156.                         long refCon )
  157. {
  158.     WindowPtr        wp;
  159.     DescType        propCode;
  160.     WindTokenBody    **tokHdl;
  161.     AEDesc            newValue;
  162.     AEDesc            textValue;
  163.     OSErr            err;
  164.  
  165.     /* Sanity check */
  166.     if ( tokenPtr->descriptorType != cWindow ){
  167.         Gripe( "\pGot wrong token type" );
  168.         return errAEEventNotHandled;
  169.     }
  170.  
  171.     tokHdl = (WindTokenBody**)(tokenPtr->dataHandle);
  172.     
  173.     wp = (*tokHdl)->theWindowPtr;
  174.     propCode = (*tokHdl)->propertyCode;
  175.     
  176.     if ( !wp ){
  177.         Gripe( "\pAttempting to set data in non-existent window" );
  178.         return errAENoSuchObject;
  179.     }
  180.     
  181.     /* Get the value to set, whatever it is */
  182.     
  183.     err = AEGetParamDesc( theAppleEventPtr,
  184.                             keyAEData,
  185.                             typeWildCard,
  186.                             &newValue );
  187.     if ( err ){
  188.         Gripe( "\pAEGetParamDesc failed to get keyAEData" );
  189.         return err;
  190.     }                        
  191.  
  192.     switch ( propCode ){
  193.         case typeNull:
  194.             /* This is a magic number for "Not A Property".  I don't know if this
  195.              * is really kosher - gotta ask, but it is a convenience.
  196.              */
  197.             
  198.             /* I don't think it makes sense to Set Data on a window */
  199.             return errAEEventNotHandled;
  200.             break;
  201.         case pName:
  202.         
  203.             /* Make sure that the name is of type text */
  204.             err = AECoerceDesc( &newValue,
  205.                                 typePString,
  206.                                 &textValue );
  207.             if ( err ){
  208.                 Gripe( "\pAECoerceDesc failed to coerce to text" );
  209.                 return err;
  210.             }
  211.             
  212.             HLock( textValue.dataHandle );
  213.             
  214.             SetWTitle( wp, *(textValue.dataHandle) );
  215.                         
  216.             HUnlock( textValue.dataHandle );
  217.             
  218.             err = AEDisposeDesc( &textValue );
  219.             
  220.             if ( err ){
  221.                 Gripe( "\pAEDisposeDesc textValue failed" );
  222.                 return err;
  223.             }
  224.             
  225.             break;
  226.         case pBounds:
  227.         case pClass:
  228.         case pHasTitleBar:
  229.         case pIndex:
  230.         case pIsModal:
  231.         case pIsResizable:
  232.         case pIsZoomed:
  233.         case pVisible:
  234.             Gripe( "\pGot a property type we do not yet implement" );
  235.             return errAENoSuchObject;
  236.             break;
  237.         default:
  238.             Gripe( "\pUnknown property type" );
  239.             return errAENoSuchObject;
  240.             break;
  241.     }
  242.     
  243.     /* At this point we are done with the newValue descriptor */
  244.     
  245.     err = AEDisposeDesc( &newValue );
  246.     
  247.     if ( err ){
  248.         Gripe( "\pAEDisposeDesc newValue failed" );
  249.         return err;
  250.     }
  251.  
  252.     return noErr;
  253. }/* WindSetDataHandler */
  254.  
  255. /* Return a Window token given a null (application) token */
  256.  
  257. pascal OSErr WindFromNull(DescType desiredClass,
  258.                             const AEDesc *container,
  259.                             DescType containerClass,
  260.                             DescType form,
  261.                             const AEDesc *selectionData,
  262.                             AEDesc *theToken,
  263.                             long LongInt)
  264. {
  265.     AEDesc            longKeyData;
  266.     WindowPtr        wp;
  267.     long            count;
  268.     WindTokenBody    tokData;
  269.     OSErr            err;
  270.  
  271.     /* Check that the container is what we intend.  This should only happen if we
  272.      * installed the token handler incorrectly.
  273.      */
  274.  
  275.     if ( container->descriptorType != typeNull )
  276.         return errAEEventNotHandled;
  277.     
  278.     /* find the window based on the key form */
  279.     
  280.     switch ( form ){
  281.         case formAbsolutePosition:
  282.             /* Make sure we really have a type long descriptor */
  283.             err = AECoerceDesc( selectionData, typeLongInteger, &longKeyData );
  284.             if ( err ){
  285.                 Gripe( "\pAECoerceDesc failed" );
  286.                 return err;
  287.             }
  288.             
  289.             count = **(long**)(longKeyData.dataHandle);
  290.             
  291.             /* We're done with the descriptor created in the coercion */
  292.             
  293.             err = AEDisposeDesc( &longKeyData );
  294.             if ( err ){
  295.                 Gripe( "\pAEDisposeDesc failed" );
  296.                 return err;
  297.             }
  298.             
  299.             /* In our particular case, we can have at most one window, but we write 
  300.              * this in a general way for reusability... scan the window list for the
  301.              * window
  302.              */
  303.              
  304.             wp = FrontWindow();
  305.             
  306.             while( count > 1 && wp != (WindowPtr)NULL ){
  307.                 wp = (WindowPtr)((WindowPeek)wp)->nextWindow;
  308.             }
  309.             
  310.             if ( wp == (WindowPtr)NULL ){
  311.                 Gripe( "\pNo window found" );
  312.                 return errAENoSuchObject;
  313.             }
  314.             
  315.             /* Actually create the token that we return */
  316.             tokData.theWindowPtr = wp;
  317.             tokData.propertyCode = typeNull;        /* This means it's not a property */
  318.             
  319.             err = AECreateDesc( desiredClass, (Ptr)&tokData, sizeof( tokData ), theToken );
  320.             if ( err ){
  321.                 Gripe( "\pAECreateDesc failed to create a token" );
  322.                 return err;
  323.             }
  324.             
  325.             return noErr;
  326.             break;
  327.         case formRelativePosition:
  328.         case formTest:
  329.         case formRange:
  330.         case formPropertyID:
  331.         case formName:
  332.             return errAEEventNotHandled;    /* Flesh this out later */
  333.             break;
  334.         default:
  335.             Gripe( "\pGot unexpected key form" );
  336.             return errAEEventNotHandled;
  337.     }
  338.         
  339.     return noErr;
  340. }
  341.  
  342. /* Return a property token given a cWindow token.  This works for any property of a window */
  343.  
  344. pascal OSErr PropFromWind(DescType desiredClass,
  345.                             const AEDesc *container,
  346.                             DescType containerClass,
  347.                             DescType form,
  348.                             const AEDesc *selectionData,
  349.                             AEDesc *theToken,
  350.                             long LongInt)
  351. {
  352.     OSErr        err;
  353.     DescType    propType;
  354.  
  355.     /* Check that the container is what we intend.  This should only happen if we
  356.      * installed the token handler incorrectly.
  357.      */
  358.  
  359.     if ( container->descriptorType != cWindow )
  360.         return errAEEventNotHandled;
  361.  
  362.     if ( form != formPropertyID ){
  363.         Gripe( "\pExpected formPropertyID" );
  364.         return errAEEventNotHandled;
  365.     }
  366.  
  367.     propType = **( (DescType**)(selectionData->dataHandle) );
  368.  
  369.     /* All we really do here is shove the property type into the token, if we
  370.      * know about the property type
  371.      */
  372.  
  373.     switch ( propType ){
  374.         case pName:
  375.             break;
  376.         case pBounds:
  377.         case pClass:
  378.         case pHasTitleBar:
  379.         case pIndex:
  380.         case pIsModal:
  381.         case pIsResizable:
  382.         case pIsZoomed:
  383.         case pVisible:
  384.             Gripe( "\pGot a property type we do not yet implement" );
  385.             return errAENoSuchObject;
  386.             break;
  387.         default:
  388.             Gripe( "\pUnknown property type" );
  389.             return errAENoSuchObject;
  390.             break;
  391.     }
  392.  
  393.     /* All we do in the token is put the propType into it.  We can start with the
  394.      * container descriptor as it has some of the fields filled in already.
  395.      */
  396.     
  397.     err = AEDuplicateDesc( container, theToken );
  398.     if ( err ){
  399.         Gripe( "\pAEDuplicateDesc failed" );
  400.         return err;
  401.     }
  402.     
  403.     (*(WindTokenBody**)(theToken->dataHandle))->propertyCode = propType;
  404.     
  405.     return noErr;
  406. }
  407.  
  408. /*
  409.  * Descriptor packing routines
  410.  */
  411.  
  412. /* Create a formAbsolutePosition window descriptor */
  413.  
  414. OSErr BuildWindowSpecifier( AEDesc *specPtr, long whichWindow )
  415. {
  416.     AEDesc    nullDesc;
  417.     AEDesc    nullSpec;
  418.     AEDesc    whichDesc;
  419.     OSErr    err;
  420.     
  421.     /* Create the descriptor for the container (the application, or null) */
  422.  
  423.     err = AECreateDesc( typeNull, (Ptr)NULL, (Size)0, &nullDesc );
  424.     if ( err )
  425.         return err;
  426.     
  427.     /* Create the key data, which gives the window number */
  428.     
  429.     err = CreateOffsetDescriptor( whichWindow, &whichDesc );
  430.     if ( err )
  431.         return err;
  432.  
  433.     /* Create the Object Specifier for the window */
  434.     
  435.     err = CreateObjSpecifier( cWindow,
  436.                                 &nullDesc,
  437.                                 formAbsolutePosition,
  438.                                 &whichDesc,
  439.                                 true,                    /* Dispose of input descriptors */
  440.                                 specPtr );                /* specPtr is the value we return */
  441.     return err;
  442. }